package com.hb.C_Lambda表达式和集合.D_集合

import java.util.*
import kotlin.collections.HashSet


/**
 * 由元素构造
 * 创建集合的最常用方法是使用标准库函数 listOf<T>()、setOf<T>()、mutableListOf<T>()、mutableSetOf<T>()。
 * 如果以逗号分隔的集合元素列表作为参数，编译器会自动检测元素类型。创建空集合时，须明确指定类型。
 *
 * 同样的，Map 也有这样的函数 mapOf() 与 mutableMapOf()。映射的键和值作为 Pair 对象传递（通常使用中缀函数 to 创建）。
 */
fun main() {
    val numbersSet = setOf("one", "two", "three", "four")
    val emptySet = mutableSetOf<String>()

    val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)

    /**
     *  注意，to 符号创建了一个短时存活的 Pair 对象，因此建议仅在性能不重要时才使用它。
     *  为避免过多的内存使用，请使用其他方法。例如，可以创建可写 Map 并使用写入操作填充它。
     *  apply() 函数可以帮助保持初始化流畅。
     */
    val numbersMap2 = mutableMapOf<String, String>().apply { this["one"] = "1"; this["two"] = "2" }

    /**
     * 空集合
     * 还有用于创建没有任何元素的集合的函数：emptyList()、emptySet() 与 emptyMap()。 创建空集合时，应指定集合将包含的元素类型。
     */
    val empty = emptyList<String>()

    /**
     * list 的初始化函数
     * 对于 List，有一个接受 List 的大小与初始化函数的构造函数，该初始化函数根据索引定义元素的值。
     */
    val doubled = List(3, { it * 2 })  // 如果你想操作这个集合，应使用 MutableList
    println(doubled)

    /**
     * 具体类型构造函数
     * 要创建具体类型的集合，例如 ArrayList 或 LinkedList，可以使用这些类型的构造函数。 类似的构造函数对于 Set 与 Map 的各实现中均有提供。
     */
    val linkedList = LinkedList<String>(listOf("one", "two", "three"))
    val presizedSet = HashSet<Int>(32)

    /**
     * 复制
     * 要创建与现有集合具有相同元素的集合，可以使用复制操作。标准库中的集合复制操作创建了具有相同元素引用的 浅 复制集合。
     * 因此，对集合元素所做的更改会反映在其所有副本中。在特定时刻通过集合复制函数，例如toList()、toMutableList()、toSet() 等等。
     * 创建了集合的快照。 结果是创建了一个具有相同元素的新集合 如果在源集合中添加或删除元素，则不会影响副本。副本也可以独立于源集合进行更改。
     */

    val sourceList = mutableListOf(1, 2, 3)
    val copyList = sourceList.toMutableList()
    val readOnlyCopyList = sourceList.toList()
    sourceList.add(4)
    println("Copy size: ${copyList.size}")

    //readOnlyCopyList.add(4)             // 编译异常
    println("Read-only copy size: ${readOnlyCopyList.size}")
}